{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/Users/zhangjunwu/anaconda/envs/Tableau-Python-Server/lib/python2.7/site-packages/sklearn/cross_validation.py:41: DeprecationWarning: This module was deprecated in version 0.18 in favor of the model_selection module into which all the refactored classes and functions are moved. Also note that the interface of the new CV iterators are different from that of this module. This module will be removed in 0.20.\n",
      "  \"This module will be removed in 0.20.\", DeprecationWarning)\n",
      "/Users/zhangjunwu/anaconda/envs/Tableau-Python-Server/lib/python2.7/site-packages/sklearn/grid_search.py:42: DeprecationWarning: This module was deprecated in version 0.18 in favor of the model_selection module into which all the refactored classes and functions are moved. This module will be removed in 0.20.\n",
      "  DeprecationWarning)\n"
     ]
    }
   ],
   "source": [
    "import math\n",
    "import numpy as np\n",
    "import pandas as pd\n",
    "from sklearn.grid_search import GridSearchCV\n",
    "from sklearn.linear_model import LogisticRegressionCV\n",
    "from sklearn.naive_bayes import GaussianNB\n",
    "from sklearn.cross_validation import cross_val_score, cross_val_predict, StratifiedKFold \n",
    "from sklearn import preprocessing, metrics, svm, ensemble\n",
    "from sklearn.metrics import accuracy_score, classification_report\n",
    "import tabpy_client "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style>\n",
       "    .dataframe thead tr:only-child th {\n",
       "        text-align: right;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: left;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>sepal_length</th>\n",
       "      <th>sepal_width</th>\n",
       "      <th>petal_length</th>\n",
       "      <th>petal_width</th>\n",
       "      <th>Class</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>5.1</td>\n",
       "      <td>3.5</td>\n",
       "      <td>1.4</td>\n",
       "      <td>0.2</td>\n",
       "      <td>setosa</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>4.9</td>\n",
       "      <td>3.0</td>\n",
       "      <td>1.4</td>\n",
       "      <td>0.2</td>\n",
       "      <td>setosa</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>4.7</td>\n",
       "      <td>3.2</td>\n",
       "      <td>1.3</td>\n",
       "      <td>0.2</td>\n",
       "      <td>setosa</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>4.6</td>\n",
       "      <td>3.1</td>\n",
       "      <td>1.5</td>\n",
       "      <td>0.2</td>\n",
       "      <td>setosa</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>5.0</td>\n",
       "      <td>3.6</td>\n",
       "      <td>1.4</td>\n",
       "      <td>0.2</td>\n",
       "      <td>setosa</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>5.4</td>\n",
       "      <td>3.9</td>\n",
       "      <td>1.7</td>\n",
       "      <td>0.4</td>\n",
       "      <td>setosa</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>4.6</td>\n",
       "      <td>3.4</td>\n",
       "      <td>1.4</td>\n",
       "      <td>0.3</td>\n",
       "      <td>setosa</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>5.0</td>\n",
       "      <td>3.4</td>\n",
       "      <td>1.5</td>\n",
       "      <td>0.2</td>\n",
       "      <td>setosa</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>8</th>\n",
       "      <td>4.4</td>\n",
       "      <td>2.9</td>\n",
       "      <td>1.4</td>\n",
       "      <td>0.2</td>\n",
       "      <td>setosa</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9</th>\n",
       "      <td>4.9</td>\n",
       "      <td>3.1</td>\n",
       "      <td>1.5</td>\n",
       "      <td>0.1</td>\n",
       "      <td>setosa</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   sepal_length  sepal_width  petal_length  petal_width   Class\n",
       "0           5.1          3.5           1.4          0.2  setosa\n",
       "1           4.9          3.0           1.4          0.2  setosa\n",
       "2           4.7          3.2           1.3          0.2  setosa\n",
       "3           4.6          3.1           1.5          0.2  setosa\n",
       "4           5.0          3.6           1.4          0.2  setosa\n",
       "5           5.4          3.9           1.7          0.4  setosa\n",
       "6           4.6          3.4           1.4          0.3  setosa\n",
       "7           5.0          3.4           1.5          0.2  setosa\n",
       "8           4.4          2.9           1.4          0.2  setosa\n",
       "9           4.9          3.1           1.5          0.1  setosa"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Iris dataset: http://aima.cs.berkeley.edu/data/iris.csv\n",
    "df =  pd.read_csv('./iris2.csv', header=0)\n",
    "# Take a look at the structure of the file\n",
    "df.head(n=10)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style>\n",
       "    .dataframe thead tr:only-child th {\n",
       "        text-align: right;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: left;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>sepal_length</th>\n",
       "      <th>sepal_width</th>\n",
       "      <th>petal_length</th>\n",
       "      <th>petal_width</th>\n",
       "      <th>Class</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>5.1</td>\n",
       "      <td>3.5</td>\n",
       "      <td>1.4</td>\n",
       "      <td>0.2</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>4.9</td>\n",
       "      <td>3.0</td>\n",
       "      <td>1.4</td>\n",
       "      <td>0.2</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>4.7</td>\n",
       "      <td>3.2</td>\n",
       "      <td>1.3</td>\n",
       "      <td>0.2</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>4.6</td>\n",
       "      <td>3.1</td>\n",
       "      <td>1.5</td>\n",
       "      <td>0.2</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>5.0</td>\n",
       "      <td>3.6</td>\n",
       "      <td>1.4</td>\n",
       "      <td>0.2</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>5.4</td>\n",
       "      <td>3.9</td>\n",
       "      <td>1.7</td>\n",
       "      <td>0.4</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>4.6</td>\n",
       "      <td>3.4</td>\n",
       "      <td>1.4</td>\n",
       "      <td>0.3</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>5.0</td>\n",
       "      <td>3.4</td>\n",
       "      <td>1.5</td>\n",
       "      <td>0.2</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>8</th>\n",
       "      <td>4.4</td>\n",
       "      <td>2.9</td>\n",
       "      <td>1.4</td>\n",
       "      <td>0.2</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9</th>\n",
       "      <td>4.9</td>\n",
       "      <td>3.1</td>\n",
       "      <td>1.5</td>\n",
       "      <td>0.1</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   sepal_length  sepal_width  petal_length  petal_width  Class\n",
       "0           5.1          3.5           1.4          0.2      0\n",
       "1           4.9          3.0           1.4          0.2      0\n",
       "2           4.7          3.2           1.3          0.2      0\n",
       "3           4.6          3.1           1.5          0.2      0\n",
       "4           5.0          3.6           1.4          0.2      0\n",
       "5           5.4          3.9           1.7          0.4      0\n",
       "6           4.6          3.4           1.4          0.3      0\n",
       "7           5.0          3.4           1.5          0.2      0\n",
       "8           4.4          2.9           1.4          0.2      0\n",
       "9           4.9          3.1           1.5          0.1      0"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Use LabelEncoder to convert textual classifications to numeric. \n",
    "# We will use the same encoder later to convert them back.\n",
    "encoder = preprocessing.LabelEncoder()\n",
    "df['Class'] = encoder.fit_transform(df['Class'])\n",
    "\n",
    "# Check the result of the transform\n",
    "df.head(n=10)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "pass\n"
     ]
    }
   ],
   "source": [
    "# Split columns into independent/predictor variables vs dependent/response/outcome variable\n",
    "X = np.array(df.drop(['Class'], 1))\n",
    "y = np.array(df['Class'])\n",
    "\n",
    "# Scale the data. We will use the same scaler later for scoring function\n",
    "scaler = preprocessing.StandardScaler().fit(X)\n",
    "X = scaler.transform(X)\n",
    "\n",
    "# 10 fold stratified cross validation\n",
    "kf = StratifiedKFold(y, n_folds=10, random_state=None, shuffle=True)\n",
    "\n",
    "# Define the parameter grid to use for tuning the Support Vector Machine\n",
    "parameters = [{'kernel': ['rbf'], 'gamma': [1e-3, 1e-4],\n",
    "                     'C': [1, 10, 100, 1000]},\n",
    "                    {'kernel': ['linear'], 'C': [1, 10, 100, 1000]}]\n",
    "\n",
    "# Pick accuracy as the goal you're optimizing\n",
    "scoringmethods = ['accuracy']\n",
    "\n",
    "print 'pass'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "~~~ Hyper-parameter tuning for best accuracy ~~~\n",
      "Scores for different parameter combinations in the grid:\n",
      "  0.853 (+/-0.036) for {'kernel': 'rbf', 'C': 1, 'gamma': 0.001}\n",
      "  0.853 (+/-0.036) for {'kernel': 'rbf', 'C': 1, 'gamma': 0.0001}\n",
      "  0.900 (+/-0.031) for {'kernel': 'rbf', 'C': 10, 'gamma': 0.001}\n",
      "  0.853 (+/-0.036) for {'kernel': 'rbf', 'C': 10, 'gamma': 0.0001}\n",
      "  0.967 (+/-0.017) for {'kernel': 'rbf', 'C': 100, 'gamma': 0.001}\n",
      "  0.900 (+/-0.031) for {'kernel': 'rbf', 'C': 100, 'gamma': 0.0001}\n",
      "  0.967 (+/-0.022) for {'kernel': 'rbf', 'C': 1000, 'gamma': 0.001}\n",
      "  0.967 (+/-0.017) for {'kernel': 'rbf', 'C': 1000, 'gamma': 0.0001}\n",
      "  0.973 (+/-0.022) for {'kernel': 'linear', 'C': 1}\n",
      "  0.967 (+/-0.022) for {'kernel': 'linear', 'C': 10}\n",
      "  0.973 (+/-0.022) for {'kernel': 'linear', 'C': 100}\n",
      "  0.980 (+/-0.021) for {'kernel': 'linear', 'C': 1000}\n",
      "\n",
      "Classification report:\n",
      "             precision    recall  f1-score   support\n",
      "\n",
      "          0       1.00      1.00      1.00        50\n",
      "          1       0.98      0.98      0.98        50\n",
      "          2       0.98      0.98      0.98        50\n",
      "\n",
      "avg / total       0.99      0.99      0.99       150\n",
      "\n",
      "Best model:\n",
      "SVC(C=1000, cache_size=200, class_weight=None, coef0=0.0,\n",
      "  decision_function_shape='ovr', degree=3, gamma='auto', kernel='linear',\n",
      "  max_iter=-1, probability=False, random_state=None, shrinking=True,\n",
      "  tol=0.001, verbose=False)\n",
      "Accuracy: 0.987\n",
      "\n"
     ]
    }
   ],
   "source": [
    "# Iterate through different metrics looking for best parameter set\n",
    "for score in scoringmethods:\n",
    "    print(\"~~~ Hyper-parameter tuning for best %s ~~~\" % score)\n",
    "    \n",
    "    # Setup for grid search with cross-validation for Support Vector Machine\n",
    "    # n_jobs=-1 for parallel execution using all available cores\n",
    "    svmclf = GridSearchCV(svm.SVC(C=1), parameters, cv=kf, scoring=score,n_jobs=1)\n",
    "    svmclf.fit(X, y)\n",
    "    \n",
    "    # Show each result from grid search\n",
    "    print(\"Scores for different parameter combinations in the grid:\")\n",
    "    for params, mean_score, scores in svmclf.grid_scores_:\n",
    "        print(\"  %0.3f (+/-%0.03f) for %r\"\n",
    "              % (mean_score, scores.std() / 2, params)) \n",
    "    print(\"\")\n",
    "# Show classification report for the best model (set of parameters) run over the full dataset\n",
    "print(\"Classification report:\")\n",
    "y_pred = svmclf.predict(X)\n",
    "print(classification_report(y, y_pred))\n",
    "    \n",
    "# Show the definition of the best model\n",
    "print(\"Best model:\")\n",
    "print(svmclf.best_estimator_)\n",
    "    \n",
    "# Show accuracy \n",
    "print(\"Accuracy: %0.3f\" % accuracy_score(y, y_pred, normalize=True))\n",
    "print(\"\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Classification report:\n",
      "             precision    recall  f1-score   support\n",
      "\n",
      "          0       0.79      0.96      0.86        50\n",
      "          1       0.85      0.70      0.77        50\n",
      "          2       0.96      0.92      0.94        50\n",
      "\n",
      "avg / total       0.87      0.86      0.86       150\n",
      "\n",
      "Accuracy: 0.860\n"
     ]
    }
   ],
   "source": [
    "# Logistic regression with 10 fold stratified cross-validation using model specific cross-validation in scikit-learn\n",
    "lgclf = LogisticRegressionCV(Cs=list(np.power(10.0, np.arange(-10, 10))),penalty='l2',scoring='roc_auc',cv=kf)\n",
    "lgclf.fit(X, y)\n",
    "y_pred = lgclf.predict(X)\n",
    "\n",
    "# Show classification report for the best model (set of parameters) run over the full dataset\n",
    "print(\"Classification report:\")\n",
    "print(classification_report(y, y_pred))\n",
    "\n",
    "# Show accuracy\n",
    "print(\"Accuracy: %0.3f\" % accuracy_score(y, y_pred, normalize=True))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Accuracy: 0.947\n"
     ]
    }
   ],
   "source": [
    "# Naive Bayes with 10 fold stratified cross-validation\n",
    "nbclf = GaussianNB()\n",
    "scores = cross_val_score(nbclf, X, y, cv=kf, scoring='accuracy')\n",
    "\n",
    "# Show accuracy statistics for cross-validation\n",
    "print(\"Accuracy: %0.3f\" % (scores.mean()))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "connect success\n"
     ]
    }
   ],
   "source": [
    "# Connect to TabPy server using the client library\n",
    "connection = tabpy_client.Client('http://localhost:9004/')\n",
    "print 'connect success'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "define success\n"
     ]
    }
   ],
   "source": [
    "# The scoring function that will use the SVM Classifier to classify new data points\n",
    "def iris_classiffier2(sepal_length,sepal_width,petal_length,petal_width):\n",
    "    X = np.column_stack([sepal_length,sepal_width,petal_length,petal_width])\n",
    "    X = scaler.transform(X)\n",
    "    return encoder.inverse_transform(svmclf.predict(X)).tolist()\n",
    "print 'define success'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "deploy success!\n"
     ]
    }
   ],
   "source": [
    "# Publish the function to TabPy server so it can be used from Tableau\n",
    "# Using the name Iris_Classiffier2 and a short description of what it does\n",
    "connection.deploy('Iris_Classiffier2',\n",
    "                  iris_classiffier2,\n",
    "                  'Returns Iris dataset prediction',override=True)\n",
    "print 'deploy success!'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "tableau",
   "language": "python",
   "name": "tableau"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.13"
  },
  "toc": {
   "colors": {
    "hover_highlight": "#DAA520",
    "navigate_num": "#000000",
    "navigate_text": "#333333",
    "running_highlight": "#FF0000",
    "selected_highlight": "#FFD700",
    "sidebar_border": "#EEEEEE",
    "wrapper_background": "#FFFFFF"
   },
   "moveMenuLeft": true,
   "nav_menu": {
    "height": "12px",
    "width": "252px"
   },
   "navigate_menu": true,
   "number_sections": true,
   "sideBar": true,
   "threshold": 4,
   "toc_cell": false,
   "toc_section_display": "block",
   "toc_window_display": false,
   "widenNotebook": false
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
